package ms.unicorn.diagram.figures;

import java.lang.reflect.Constructor;

import ms.unicorn.UnicornService;
import ms.unicorn.dsl.IBorderEx;
import ms.unicorn.dsl.IFigureEx;
import ms.unicorn.dsl.ITheme;
import ms.unicorn.dsl.impl.Theme;
import ms.unicorn.dsl.utils.ExceptionUtil;
import ms.unicorn.util.NotificationService;

import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
import org.eclipse.gmf.runtime.draw2d.ui.figures.IOvalAnchorableFigure;
import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
import org.eclipse.gmf.runtime.notation.GradientStyle;

public class EntityFigure extends NodeFigure implements IFigureEx, IOvalAnchorableFigure {
	
	private String name;
	private int flag;
	private ITheme theme = Theme.DEFAULT;
	
	public EntityFigure() {
				
	}
	
	@Override
	public void paint(Graphics graphics) {
		// update theme
		Object resolve = UnicornService.getNotificationService().dispatch(this, NotificationService.CHANNEL_THEME, NotificationService.THEME_RESOLVE, theme);
		if (resolve instanceof ITheme)
			theme = (ITheme) resolve;
		super.paint(graphics);
	}
	
	@Override
	public Rectangle getClientArea(Rectangle r) {
		if (theme != null && theme.getBorderEx() != null) {
			Insets insets = theme.getBorderEx().getInsets(this, theme);
			Rectangle clientArea = super.getClientArea(r);
			return clientArea.shrink(insets);
		}
		
		return super.getClientArea(r);
	}
	
	@Override
    protected void paintFigure(Graphics graphics) {
		if (theme != null) {
        	if (theme.getBorder() != getBorder())
        		setBorder(theme.getBorder());
        	if (getBorder() instanceof IBorderEx) 
        		((IBorderEx)getBorder()).paint(this, graphics, NO_INSETS, theme);
        	else
        		super.paintBorder(graphics);
        }
        else
        	super.paintBorder(graphics);
    }
	
    @Override
    protected void paintBorder(Graphics graphics) {
        
    }
    
    protected void paintBackground(Graphics graphics, Rectangle rectangle) {
    	int corner = 10;
		if(isUsingGradient()) {			
			applyTransparency(graphics);
			boolean isVertical = (getGradientStyle() == GradientStyle.VERTICAL) ? true : false;
			if(isVertical && rectangle.height>((3*corner)/2)){
				Rectangle rect1= new Rectangle(rectangle.getLocation(),new Dimension(rectangle.width,corner));
				Rectangle rect2= new Rectangle(rectangle.x,rectangle.y+rectangle.height-corner,rectangle.width,corner);;
				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor2()));
				graphics.fillRoundRectangle(rect1,corner,corner);
				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor1()));
				graphics.fillRoundRectangle(rect2,corner,corner);

				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor1()));
				graphics.setForegroundColor(FigureUtilities.integerToColor(getGradientColor2()));
				Rectangle rect= new Rectangle(rectangle.x,rectangle.y+corner/2,rectangle.width,rectangle.height-corner);
				graphics.fillGradient(rect, true);
			}
			else if(!isVertical && rectangle.width>((3*corner)/2)){
				Rectangle rect1= new Rectangle(rectangle.getLocation(),new Dimension(corner,rectangle.height));
				Rectangle rect2= new Rectangle(rectangle.x+rectangle.width-corner,rectangle.y,corner,rectangle.height);
				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor2()));
				graphics.fillRoundRectangle(rect1,corner,corner);
				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor1()));
				graphics.fillRoundRectangle(rect2,corner,corner);

				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor1()));
				graphics.setForegroundColor(FigureUtilities.integerToColor(getGradientColor2()));
				Rectangle rect= new Rectangle(rectangle.x+corner/2, rectangle.y,rectangle.width-corner,rectangle.height);
				graphics.fillGradient(rect, false);
			}
			else{
				graphics.setBackgroundColor(FigureUtilities.integerToColor(getGradientColor1()));
				graphics.setForegroundColor(FigureUtilities.integerToColor(getGradientColor2()));
				graphics.fillRoundRectangle(rectangle,corner,corner);
			}
		}
		else {
			graphics.setBackgroundColor(getBackgroundColor());
			graphics.setForegroundColor(getForegroundColor());
			graphics.fillRoundRectangle(rectangle,corner,corner);
		}
	}

    @Override
    protected ConnectionAnchor createDefaultAnchor() {
    	if (theme.getBorderEx() != null) {
    		return theme.getBorderEx().createAnchor(this);
    	}
    	return new SlidableAnchorEx(this);
    }
    
    @Override
    protected ConnectionAnchor createAnchor(PrecisionPoint p) {
    	//return createDefaultAnchor();
    	if (theme.getBorderEx() != null) {
    		return theme.getBorderEx().createAnchor(this, p);
    	}
    	return super.createConnectionAnchor(p);
    }

    @Override
    protected double getSlidableAnchorArea() {
    	if (theme.getBorderEx() != null && theme.getBorderEx().getSlidableAnchorArea() > 0)
    		return theme.getBorderEx().getSlidableAnchorArea();
        return  super.getSlidableAnchorArea();
    }
    
    @Override
    public PointList getPolygonPoints() {
    	if (theme.getBorderEx() != null) {
    		PointList points = theme.getBorderEx().getPolyPoints(this);
    		if (points != null) return points;
    	}
    	return super.getPolygonPoints();
    }
    
    @Override
    protected boolean isDefaultAnchorArea(PrecisionPoint p) {
    	return super.isDefaultAnchorArea(p);
    }

    
	@Override
	public ITheme getTheme() {
		return this.theme;
	}

	@Override
	public void setTheme(ITheme theme) {
		this.theme = theme;
	}


	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int getFlag() {
		return this.flag;
	}

	@Override
	public void setFlag(int flag) {
		this.flag = flag;
	}

	@Override
	public Rectangle getOvalBounds() {
		return getBounds();
	}
}
